package org.lh.ibernate.config;


import org.lh.ibernate.core.IDbPool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

//数据库连接池
public class DbPool implements IDbPool {

    private Vector<DbPoolConn> dbPoolConnVector=new Vector<>();
    private static String DRIVER;
    private static String URL;
    private static String USERNAME;
    private static String PASSWORD;
    private static  int INITCOUNT;
    private static  int STEP;
    private static  int MAXCOUNT;


    /*
    *
    * @author idea
    * @date 2018/7/11
    * @param [count]
    * @return void
    * @des 创建连接池的核心
    */
    @Override
    public void createDbPoolConn(int count) throws Exception {
        if(count>MAXCOUNT||(count+dbPoolConnVector.size())>MAXCOUNT){
            throw new Exception("数据库初始化出错！链接数太大");
        }else {
            for(int i=0;i<count;i++){
                Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
                DbPoolConn dbPoolConn=new DbPoolConn(conn,false);
                dbPoolConnVector.add(dbPoolConn);  //加入向量队列中
            }
        }
    }
    
    public  DbPool() throws Exception {
        init();
        try {
            Class.forName(DRIVER);  //加载驱动
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        createDbPoolConn(INITCOUNT);
    }

    private void init(){
        this.DRIVER=DbConfig.DRIVER;
        this.URL=DbConfig.URL;
        this.USERNAME=DbConfig.USERNAME;
        this.PASSWORD=DbConfig.PASSWORD;
        this.INITCOUNT=DbConfig.INITCOUNT;
        this.STEP=DbConfig.STEP;
        this.MAXCOUNT=DbConfig.MAXCOUNT;
    }


    //如果链接数量大于初始化数值，创建新的链接
    @Override
    public DbPoolConn getDbPoolConn() throws Exception {
        if(dbPoolConnVector.size()<INITCOUNT){
            throw  new  Exception("链接初始化时出错！");
        }
        if(dbPoolConnVector.size()>INITCOUNT){ //如果链接超多了初始连接数量
          createDbPoolConn(STEP);
          DbPoolConn dbPoolConn=this.getRealConnectionFromPool();
          return dbPoolConn;
        }else if(dbPoolConnVector.size()<MAXCOUNT){
            DbPoolConn dbPoolConn=this.getRealConnectionFromPool();
            return dbPoolConn;
        }else{
            throw new Exception("对不起，连接池已满");
        }
    }

    //如果链接已被占用，则创建新的链接，否则继续用原来的连接
    private synchronized DbPoolConn getRealConnectionFromPool() throws SQLException {
        if(dbPoolConnVector.size()>0){
            for (DbPoolConn dbPoolConn:dbPoolConnVector){
                if(!dbPoolConn.isBusy){
                    //判断该链接是否有被释放掉(3秒内可以被连接上)
                    if(dbPoolConn.connection.isValid(3000)){
                        dbPoolConn.isBusy=true;
                        return dbPoolConn;
                    }else{
                        Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
                        dbPoolConn.setBusy(true);
                        dbPoolConn.setConnection(conn);
                        return dbPoolConn;
                    }
                }
            }
        }
        return null;
    }
}
